package domain.scenes;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;

import com.uqbar.vainilla.GameComponent;
import com.uqbar.vainilla.appearances.Sprite;
import components.decoration.ExpirableLabel;
import components.scenes.CollisionablesScene;

import domain.components.IndicadorActualWorm;
import domain.components.WeaponsComponent;
import domain.game.BattleManager;
import domain.game.KeysHandler;
import domain.game.Team;
import domain.terrain.MatrixComponent;
import domain.terrain.Parser;
import domain.terrain.SquareGround;
import domain.weapon.Explosion;
import domain.worm.Worm;

public class MainGameScene extends CollisionablesScene {

	private BattleManager battleManager;
	private KeysHandler keysHandler;
	private MatrixComponent terrain;
	private int terrainWidth;
	private BufferedImage map;
	private BufferedImage mapImage;
	private BufferedImage background;
	private GameComponent terrainImage;
	private Worm currentWorm;
	private List<GameComponent> LabelTeam = new ArrayList<GameComponent>();
	private List<GameComponent> indicadorActualWorm = new ArrayList<GameComponent>();
	
	public MainGameScene(int teams, int wormsPerTeam, int mapNumber) {
		super(10000, 10000, 1000, 1000);

		this.initTerrains(mapNumber);
		this.terrainWidth = map.getWidth();
		this.keysHandler = new KeysHandler();

		this.initTeams(teams, wormsPerTeam);
		
		this.addComponent(keysHandler);
		
		

	}

	private void initTerrains(int mapNumber) {
		this.map= Parser.image("/map/terreno" + mapNumber + ".PNG");
		
		this.mapImage = Parser.scaledBufferedImageFrom(map.getWidth(), map.getHeight(), "/map/textura-tierra.PNG");
		
	    
		this.background =Parser.image("/map/bluesky.PNG");
		
		this.mapImage = Parser.applyMask(mapImage, map);
		
		this.setTerrain(new MatrixComponent(map));
		
		
		this.terrainImage = new GameComponent();
		Sprite sp = new Sprite(mapImage);
		terrainImage.setAppearance(sp);
		this.addComponent(terrainImage);
		
		//FONDO
		GameComponent fondo = new GameComponent();
		Sprite f = new Sprite(this.background);
		f = f.scaleTo(800, 800);
		fondo.setZ(-2);
		fondo.setAppearance(f);
		this.addComponent(fondo);
		
		//BORDES
		this.addCollisionable(new SquareGround(20, 1400, 820, -500));
		this.addCollisionable(new SquareGround(20, 1400, -50, -500));
		this.addCollisionable(new SquareGround(799, 20, 0, 790));
		this.addCollisionable(new SquareGround(799, 20, 0, -500));
	}

	private void initTeams(int teams, int wormsPerTeam) {
		this.setBattleManager(new BattleManager(teams));
		Worm currentWorm;
		int deltaXposs = this.terrainWidth/ (teams*wormsPerTeam + 1);
		int currentDelta = deltaXposs;
		for (int team = 0; team< teams; team++){
			for (int worm = 0; worm < wormsPerTeam; worm ++){
				currentWorm = new Worm(currentDelta, 20);
				currentDelta += deltaXposs;
				this.battleManager.addWorm(currentWorm, team);
				this.addCollisionable(currentWorm);
			}
		}
		this.currentWorm = this.battleManager.getCurrentWorm();
	}

	public void explosionOn(Explosion explosion) {
		explosion.damage(this);
		Graphics2D g = this.map.createGraphics();
	    g.setColor(Color.WHITE);
	    g.fillOval((int)explosion.getX(), (int)explosion.getY(), explosion.getDiameter(), explosion.getHeight());
	    
	    this.terrainImage.setAppearance(new Sprite(Parser.applyMaskOn(this.mapImage, this.map, 
	    		(int)explosion.getX(), (int)explosion.getY(), explosion.getDiameter(), explosion.getHeight())));
	}

	public Worm currentWorm() {
		return this.currentWorm;
	}

	public BattleManager getBattleManager() {
		return battleManager;
	}

	public void setBattleManager(BattleManager battleManager) {
		this.battleManager = battleManager;
	}

	public KeysHandler getKeysHandler() {
		return keysHandler;
	}

	public void setKeysHandler(KeysHandler keysHandler) {
		this.keysHandler = keysHandler;
	}

	public MatrixComponent getTerrain() {
		return terrain;
	}

	public void setTerrain(MatrixComponent terrain) {
		this.terrain = terrain;
	}

	public void changeTurn() {
		//TEST
		if (!this.battleManager.isGameOver()){
			this.getKeysHandler().transition(2, this.getKeysHandler().playingState());
			this.addComponent(new ExpirableLabel("NEXT TURN", 
					new  Font(Font.DIALOG, Font.BOLD, 55), Color.RED, 2, 200, 200));
			this.battleManager.changeTurn();
			this.currentWorm =  this.battleManager.getCurrentWorm();
		}
		else{
			this.getKeysHandler().transition(4, this.getKeysHandler().gameOverState());
		}
	}

	public void wormDied(Worm worm) {
		if(this.getBattleManager().getCurrentWorm().equals(worm)){
			this.getBattleManager().wormDied(worm);
			this.changeTurn();
		}
		else{
			this.getBattleManager().wormDied(worm);
		}
		this.removeCollisionable(worm);

	}

	public void wormDamaged(Worm worm, double dmg) {
		this.addComponent(new ExpirableLabel(String.valueOf((int)dmg), new Font(Font.MONOSPACED, Font.PLAIN, 15), Color.RED, 2, worm.getX(), worm.getY()));
	}
	
	public void powerWeapon(Worm worm, double power){
		this.addComponent(new ExpirableLabel(String.valueOf((int)power), new Font(Font.MONOSPACED, Font.PLAIN, 60), Color.WHITE, 0, worm.getX(), worm.getY()-30));
	}
	
	public void gameOver(Team winner){
		this.getGame().setCurrentScene(new EndScene("Team " + winner.getTeamId()));
	}

	public void gameOver() {
		this.gameOver(this.battleManager.winner());
	}

	public void restart() {
		this.getGame().setCurrentScene(new GameOptionsScene());
	}
	
	public void changeWeapon(String path){
		this.addComponent(new WeaponsComponent(path));
	}

	public void teamId(Worm worm) {
		ExpirableLabel el = new ExpirableLabel(String.valueOf("Health "+ (int)worm.getHealth()+ "\n" +"Team "+worm.getTeamId()), new Font(Font.MONOSPACED, Font.PLAIN, 15), this.battleManager.getTeam(worm.getTeamId()).getTeamColor(), 10, worm.getX(), worm.getY()-worm.getDiameter()*2);
		this.LabelTeam.add(el); 
		this.addComponent(el);
	}
	
	public void removeTeamId(Worm worm){
		for(GameComponent g:this.LabelTeam){
			this.removeComponents(g);
		}
	}

	public void indicador(Worm worm) {
		IndicadorActualWorm iaw = new IndicadorActualWorm(worm.getX(), worm.getY());
		this.indicadorActualWorm.add(iaw);
		this.addComponent(iaw);
	}

	public void removeIndicador() {
		for(GameComponent g:this.indicadorActualWorm){
			this.removeComponents(g);
		}
	}


}
